import React, { useState } from 'react';
import { Form, Input, Button, Toast, Radio, ImageUploader, DatePicker } from 'antd-mobile';
import axios from './axios';
import { useNavigate } from 'react-router-dom';
import style from './Register.module.css';
import md5 from 'md5';

interface RegisterResponse {
  code: number;
  msg?: string;
}

interface SmsResponse {
  success: boolean;
  message?: string;
  code?: string;
}

interface FormErrors {
  username?: string;
  password?: string;
  confirmPassword?: string;
  birthDate?: string;
  phone?: string;
  code?: string;
}

interface ImageFile {
  url: string;
  file?: File;
}

const Register: React.FC = () => {
  const [username, setUsername] = useState<string>('');
  const [password, setPassword] = useState<string>('');
  const [confirmPassword, setConfirmPassword] = useState<string>('');
  const [gender, setGender] = useState<'男' | '女'>('男');
  const [birthDate, setBirthDate] = useState<string>('');
  const [dateVisible, setDateVisible] = useState<boolean>(false);
  const [phone, setPhone] = useState<string>('');
  const [code, setCode] = useState<string>('');
  const [isSending, setIsSending] = useState<boolean>(false);
  const [countdown, setCountdown] = useState<number>(0);
  const [isAgreed, setIsAgreed] = useState<boolean>(false);
  const [fileList, setFileList] = useState<ImageFile[]>([]);
  const [errors, setErrors] = useState<FormErrors>({
    username: '',
    password: '',
    confirmPassword: '',
    birthDate: '',
    phone: '',
    code: '',
  });
  const navigate = useNavigate();

  // 计算年龄
  const calculateAge = (birthDate: string): number => {
    if (!birthDate) return 0;
    const today = new Date();
    const birth = new Date(birthDate);
    let age = today.getFullYear() - birth.getFullYear();
    const monthDiff = today.getMonth() - birth.getMonth();

    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
      age--;
    }

    return age;
  };

  // 处理日期选择
  const handleDateConfirm = (val: Date) => {
    const dateStr = val.toISOString();
    setBirthDate(dateStr);
    setDateVisible(false);
    setErrors(prev => ({ ...prev, birthDate: validateBirthDate(dateStr) }));
  };

  // 验证用户名
  const validateUsername = (username: string): string => {
    if (!username) {
      return '请输入用户名';
    }
    if (username.length < 2 || username.length > 20) {
      return '用户名长度应在2-20个字符之间';
    }
    if (!/^[\u4e00-\u9fa5a-zA-Z0-9_]+$/.test(username)) {
      return '用户名只能包含中文、字母、数字和下划线';
    }
    return '';
  };

  // 验证密码
  const validatePassword = (password: string): string => {
    if (!password) {
      return '请输入密码';
    }
    if (password.length < 6 || password.length > 20) {
      return '密码长度应在6-20个字符之间';
    }
    if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,20}$/.test(password)) {
      return '密码必须包含字母和数字';
    }
    return '';
  };

  // 验证确认密码
  const validateConfirmPassword = (password: string, confirmPassword: string): string => {
    if (!confirmPassword) {
      return '请确认密码';
    }
    if (password !== confirmPassword) {
      return '两次输入的密码不一致';
    }
    return '';
  };

  // 验证手机号
  const validatePhone = (phone: string): string => {
    if (!phone) {
      return '请输入手机号';
    }
    const cleanPhone = phone.trim();
    if (!/^1[3-9]\d{9}$/.test(cleanPhone)) {
      return '请输入正确的手机号';
    }
    return '';
  };

  // 验证验证码
  const validateCode = (code: string): string => {
    if (!code) {
      return '请输入验证码';
    }
    if (!/^\d{4,6}$/.test(code)) {
      return '验证码格式不正确';
    }
    return '';
  };

  // 验证出生日期
  const validateBirthDate = (date: string): string => {
    if (!date) {
      return '请选择出生日期';
    }
    const age = calculateAge(date);
    if (age < 0 || age > 120) {
      return '出生日期无效';
    }
    return '';
  };

  // 格式化日期显示
  const formatDate = (date: string): string => {
    if (!date) return '';
    const d = new Date(date);
    return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日`;
  };

  // 处理图片上传
  const handleUpload = async (file: File): Promise<ImageFile | null> => {
    try {
      if (!file.type.startsWith('image/')) {
        Toast.show({ content: '请上传图片文件', duration: 2000 });
        return null;
      }
      if (file.size > 5 * 1024 * 1024) {
        Toast.show({ content: '图片大小不能超过5MB', duration: 2000 });
        return null;
      }
      return { url: URL.createObjectURL(file), file };
    } catch (error) {
      Toast.show({ content: '图片处理失败', duration: 2000 });
      return null;
    }
  };

  // 发送验证码
  const handleSendCode = async (): Promise<void> => {
    Toast.clear();

    const phoneError = validatePhone(phone);
    if (phoneError) {
      Toast.show({
        content: phoneError,
        duration: 2000
      });
      return;
    }

    try {
      Toast.show({
        icon: 'loading',
        content: '发送中...',
        duration: 0
      });

      const cleanPhone = phone.trim();
      const res = await axios.post<SmsResponse>(`/jjx/send-sms?phoneNumber=${cleanPhone}`);

      Toast.clear();

      if (res.data.success) {
        Toast.show({
          content: '验证码已发送',
          duration: 2000
        });
        sessionStorage.setItem('verificationCode', res.data.code || '');

        setIsSending(true);
        setCountdown(60);

        const timer = setInterval(() => {
          setCountdown(prev => {
            if (prev <= 1) {
              clearInterval(timer);
              setIsSending(false);
              return 0;
            }
            return prev - 1;
          });
        }, 1000);
      } else {
        Toast.show({
          content: res.data.message || '发送失败，请重试',
          duration: 2000
        });
      }
    } catch (error) {
      Toast.clear();
      const errorMsg = (error as any).response?.data?.message || '发送失败，请重试';
      Toast.show({
        content: errorMsg,
        duration: 2000
      });
      console.error('发送验证码错误:', error);
    }
  };

  // 检查手机号是否有效
  const isPhoneValid = (phone: string): boolean => {
    const cleanPhone = phone.trim();
    return /^1[3-9]\d{9}$/.test(cleanPhone);
  };

  // 注册提交
  const handleRegister = async (): Promise<void> => {
    const newErrors: FormErrors = {
      username: validateUsername(username),
      password: validatePassword(password),
      confirmPassword: validateConfirmPassword(password, confirmPassword),
      birthDate: validateBirthDate(birthDate),
      phone: validatePhone(phone),
      code: validateCode(code),
    };

    setErrors(newErrors);

    if (Object.values(newErrors).some(error => error !== '')) {
      Toast.show({
        content: '请检查输入信息',
        duration: 2000,
      });
      return;
    }

    const storedCode = sessionStorage.getItem('verificationCode');
    if (!storedCode || storedCode !== code) {
      Toast.show({
        content: '验证码错误',
        duration: 2000,
      });
      return;
    }

    if (!isAgreed) {
      Toast.show({
        content: '请同意服务条款',
        duration: 1000,
      });
      return;
    }

    try {
      Toast.show({
        icon: 'loading',
        content: '注册中...',
        duration: 0,
      });

      const formData = new FormData();
      formData.append('username', username);
      formData.append('password', md5(password));
      formData.append('gender', gender);
      formData.append('age', calculateAge(birthDate).toString());
      formData.append('phone', phone.trim());
      formData.append('code', code);

      if (fileList.length > 0 && fileList[0].file) {
        formData.append('avatar', fileList[0].file);
      }

      const res = await axios.post<RegisterResponse>('/jjx/register', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });

      Toast.clear();

      if (res.data.code === 200) {
        sessionStorage.removeItem('verificationCode');

        Toast.show({
          content: '注册成功',
          duration: 1000,
        });
        navigate('/login');
      } else {
        Toast.show({
          content: res.data.msg || '注册失败',
          duration: 2000,
        });
      }
    } catch (err) {
      Toast.clear();
      Toast.show({
        content: '注册失败',
        duration: 2000,
      });
      console.error('注册错误:', err);
    }
  };

  // 处理输入框变化时的验证
  const handleUsernameChange = (val: string) => {
    setUsername(val);
    setErrors(prev => ({ ...prev, username: validateUsername(val) }));
  };

  const handlePasswordChange = (val: string) => {
    setPassword(val);
    setErrors(prev => ({
      ...prev,
      password: validatePassword(val),
      confirmPassword: validateConfirmPassword(val, confirmPassword)
    }));
  };

  const handleConfirmPasswordChange = (val: string) => {
    setConfirmPassword(val);
    setErrors(prev => ({ ...prev, confirmPassword: validateConfirmPassword(password, val) }));
  };

  const handlePhoneChange = (val: string) => {
    const numericValue = val.replace(/\D/g, '');
    setPhone(numericValue);
    setErrors(prev => ({ ...prev, phone: validatePhone(numericValue) }));
  };

  const handleCodeChange = (val: string) => {
    const numericValue = val.replace(/\D/g, '');
    setCode(numericValue);
    setErrors(prev => ({ ...prev, code: validateCode(numericValue) }));
  };

  return (
    <div className={style.registerPage}>
      <div className={style.formWrapper}>
        <h2 className={style.title}>注册</h2>
        <Form layout='vertical' className={style.form}>
          <Form.Item label='头像'>
            <ImageUploader
              value={fileList}
              onChange={setFileList}
              upload={handleUpload}
              maxCount={1}
              showUpload={fileList.length < 1}
            />
            <div className={style.formTip}>选填，可以稍后在个人中心设置</div>
          </Form.Item>

          <Form.Item label='用户名'>
            <Input
              placeholder='请输入用户名'
              clearable
              value={username}
              onChange={handleUsernameChange}
              maxLength={20}
              className={errors.username ? style.inputError : ''}
            />
            <div className={style.formTip}>
              {errors.username || '2-20个字符，可包含中文、字母、数字和下划线'}
            </div>
          </Form.Item>

          <Form.Item label='密码'>
            <Input
              placeholder='请输入密码'
              clearable
              type="password"
              value={password}
              onChange={handlePasswordChange}
              maxLength={20}
              className={errors.password ? style.inputError : ''}
            />
            <div className={style.formTip}>
              {errors.password || '6-20个字符，必须包含字母和数字'}
            </div>
          </Form.Item>

          <Form.Item label='确认密码'>
            <Input
              placeholder='请再次输入密码'
              clearable
              type="password"
              value={confirmPassword}
              onChange={handleConfirmPasswordChange}
              maxLength={20}
              className={errors.confirmPassword ? style.inputError : ''}
            />
            <div className={style.formTip}>
              {errors.confirmPassword || '请再次输入密码进行确认'}
            </div>
          </Form.Item>

          <Form.Item label='性别'>
            <Radio.Group value={gender} onChange={val => setGender(val as '男' | '女')}>
              <div className={style.radioGroup}>
                <Radio value='男'>男</Radio>
                <Radio value='女'>女</Radio>
              </div>
            </Radio.Group>
          </Form.Item>

          <Form.Item
            label='出生日期'
            onClick={() => setDateVisible(true)}
          >
            <div className={`${style.datePickerField} ${errors.birthDate ? style.inputError : ''}`}>
              {birthDate ? formatDate(birthDate) : '点击选择出生日期'}
            </div>
            {errors.birthDate && (
              <div className={style.formWarning}>{errors.birthDate}</div>
            )}
          </Form.Item>

          <DatePicker
            visible={dateVisible}
            onClose={() => setDateVisible(false)}
            onConfirm={handleDateConfirm}
            title='选择出生日期'
            min={new Date(1900, 0, 1)}
            max={new Date()}
            precision='day'
          />

          <Form.Item label='手机号'>
            <Input
              placeholder='请输入手机号'
              clearable
              type="tel"
              value={phone}
              onChange={handlePhoneChange}
              maxLength={11}
              className={errors.phone ? style.inputError : ''}
            />
            <div className={style.formTip}>
              {errors.phone || '请输入11位手机号'}
            </div>
          </Form.Item>

          <Form.Item label='验证码'>
            <div className={style.codeInput}>
              <Input
                placeholder='请输入验证码'
                clearable
                value={code}
                onChange={handleCodeChange}
                maxLength={6}
                className={errors.code ? style.inputError : ''}
              />
              <Button
                className={style.sendButton}
                disabled={isSending || !isPhoneValid(phone)}
                onClick={handleSendCode}
              >
                {isSending ? `${countdown}s后重试` : '发送'}
              </Button>
            </div>
            <div className={style.formTip}>
              {errors.code || '请输入4-6位验证码'}
            </div>
          </Form.Item>

          <div className={style.agreement}>
            <label>
              <input
                type="checkbox"
                checked={isAgreed}
                onChange={e => setIsAgreed(e.target.checked)}
              />
              <span>注册即代表同意</span>
              <a href="#" className={style.link}>服务条款</a>
            </label>
          </div>

          <Button
            block
            color='primary'
            size='large'
            onClick={handleRegister}
            className={style.registerButton}
          >
            注册
          </Button>
        </Form>

        <div className={style.loginTip}>
          已经有账号？
          <a className={style.loginLink} onClick={() => navigate('/login')}>
            马上登录
          </a>
          <span className={style.emoji}>👉</span>
        </div>
      </div>
    </div>
  );
};

export default Register;